﻿using System;
using GACore.InputArgs;

namespace GACore.ReversiGA
{
	public class ReversiGAMapper
	{
		private Preferences gaPreferences;
		public Preferences GaPreferences
		{
			get { return gaPreferences; }
			set { gaPreferences = value; }
		}

		private Persistence persistence;
		private string gaPrefFilename;

		public ReversiGAMapper(Preferences gaPreferences)
		{
			this.gaPreferences = gaPreferences;
		}

		public ReversiGAMapper(string gaPrefFilename)
		{
			this.gaPrefFilename = gaPrefFilename;
		}

		public OptimizationFinishedArgs Start()
		{
			try
			{
				if (gaPreferences == null)
				{
					gaPreferences = LoadGAPreferences();
				}
				Controller controller = Controller.Instance;
				controller.Init(gaPreferences, new ReversiProblem());
				return controller.Optimize();
			}
			catch (Exception ex)
			{
				throw new Exception("Es ist ein Fehler mit folgender Meldung aufgetreten:" + Environment.NewLine + ex.Message);
			}
		}

		public IAsyncResult BeginStart(AsyncCallback callback, object state)
		{
			Func<OptimizationFinishedArgs> del = Start;
			var asyncState = new AsyncState(del, state);
			return del.BeginInvoke(callback, asyncState);
		}

		public OptimizationFinishedArgs EndStart(IAsyncResult asyncResult)
		{
			var asyncState = (AsyncState)asyncResult.AsyncState;
			var del = (Func<OptimizationFinishedArgs>)asyncState.Del;
			return del.EndInvoke(asyncResult);
		}

		public Preferences LoadGAPreferences()
		{
			persistence = new Persistence();
			return persistence.Load(gaPrefFilename);
		}

		public void PersistGAPreferences(Preferences preferences)
		{
			persistence = new Persistence();
			persistence.Persist(gaPrefFilename, preferences);
		}

	}
}
